<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        function abc(){
            console.log("this:",this)
        }
        abc() //普通函数调用 window
        var obj = {
        foo: function(){
                console.log(this)
            }
        }
        obj.foo; // ƒ(){console.log(this)}
        obj.foo(); // obj {foo: ƒ} 指向调用的对象

        // 实例化 指向实例化之后的对象
        var Person = function(){
            this.name = name;
            this.showInfo = function(){
                console.log("this:",this);
                console.log("this.name:",this.name);
            }
        }
        var p1 = new Person("Jack");
        p1.showInfo();


        console.log(a); //undefined 
        var a = 2;
        console.log(a)
        /**
         *var a;
          console.log(a);
          a = 2;
          console.log(a)
        */

        a = null; //制空某一个空间，释放a的空间

        // 函数作用域整体提前
        // 变量声明提前 （函数优先级高）可能会被覆盖
        foo(); // 3
        function foo() {
            console.log(1);
        }
        var foo = function() {
            console.log(2);
        };

        function foo() {
            console.log(3);
        }
        console.log(foo);  //foo = function() {console.log(2);};
        //等价于
        /*  
        function foo() {  被覆盖
            console.log(1);
        }
        */
        function foo() {
            console.log(3);
        }
        //var foo;  被忽略
        foo();
        foo = function() { //赋值
            console.log(2);
        };

        // 全局范围作用域
        // 声明提升
        // 案例1
        console.log(a) //undefined
        var a = 1;
        var a = 2;
        console.log(a); //2

        // 案例2
        console.log(add); //function add() {console.log(2);} add()2
        function add() {
            console.log(1);
        }
        function add() {
            console.log(2);
        }
        console.log(add); //function add() {console.log(2);} add()2

        // 案例3
        console.log(add); 
        var add = 1;
        function add() {
            console.log(2);
        }
        console.log(add);
        /**
         * var add;
         * function add(){};
         * cosole.log(add)  //function add(){};
         * add = 1
         * console.log(add) //1
        */ 
        
        // 案例4
        console.log(add);
        function add() {
            console.log(1);
        }
        var add = 2;
        console.log(add);
        
        // 函数作用域
        // 案例1
        var a = 1;
        function add1(a,b){
            console.log(a); //2
            console.log(sum); //undefined
            return b;
            var sum = 2;
            console.log(b);
        }
        var c = a + add1(2,3)
        console.log(c); //4

        //预编译（预解析）：
        function add1(a, b) {
            var sum;
            console.log(a);
            console.log(sum);
            return b;
            sum = 2;
            console.log(b);
        }
        var a;
        var c;
        a = 1;
        c = a + add1(2, 3);
        console.log(c);
       
        // 案例2.1
        var a = 2;
        console.log(b) //undefined
        if(true){
            console.log(b); //undefined
            var b =3;
        }
        
        // 2.2报错 函数作用域
        var a = 2;
        console.log(b);
        (function(){
            console.log(b);
            var b = 3;
        })() 

        // 2.3
        console.log("i:",i); //undefined
        console.log("j:",j) //undefined
        for(var i=0;i<5;i++){
            //...
            var j = 1;
        }
        console.log("i:",i); //5

        console.log("x:",x) //报错，未定义
        for(var i=0;i<5;i++){
            //...
            function abc(){
                var x = 1;
            }
            
        }
    </script>
</body>
</html>